using System;
using System.Collections.Generic;
using System.Linq;
using StructureMap;

namespace Nvigorate.Repository.Test
{
    public delegate void NotificationEvent(IDomainNotification notification);

    public sealed class NotificationScope : IDisposable
    {
        private INotificationBroker _broker;
        private IList<IDomainNotification> _notifications;
        public IList<IDomainNotification> Notifications { get { return _notifications; } }
        public event NotificationEvent OnEvent;

        public void AddNotification(IDomainNotification notification)
        {
            _notifications.Add(notification);
            if(OnEvent != null)
                OnEvent.Invoke(notification);
        }

        public ICommandResult GetResult()
        {
            var result = ObjectFactory.GetInstance<ICommandResult>();
            result.Notifications = new List<IDomainNotification>(_notifications);
            result.Failed = result.Notifications.OfType<IDomainException>().Count() > 0;
            return result;
        }

        public static NotificationScope Create()
        {
            return ObjectFactory.GetInstance<NotificationScope>();
        }

        public NotificationScope(INotificationBroker broker)
        {
            _broker = broker;
            _notifications = new List<IDomainNotification>();
            _broker.RegisterScope(this);
        }

        #region Implementation of IDisposable

        public void Dispose()
        {
            OnEvent = null;
            _notifications.Clear();
            _notifications = null;
            _broker.DisposeScope(this);
        }

        #endregion
    }
}